﻿using DoNet.Common.Result;
using DoNet.Extensions.Common;
using DoNet.Extensions.Setups;
using DoNet.System.IServices;
using DoNet.System.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using System.Reflection;
using UAParser;

namespace DoNet.Extensions.Filters
{
    /// <summary>
    /// 表示一个特性，该特性用于全局捕获程序运行异常信息。
    /// </summary>
    public class GlobalExceptionsFilter : IExceptionFilter
    {
        /// <summary>
        /// 
        /// </summary>
        private readonly ILogService _service;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="service"></param>
        public GlobalExceptionsFilter(ILogService service)
        {
            _service = service;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        public void OnException(ExceptionContext context)
        {
            var exception = context.Exception;
            var httpContext = context.HttpContext;
            var httpRequest = httpContext.Request;
            var type = MethodBase.GetCurrentMethod()?.DeclaringType;
            CommonResult result = new CommonResult();
            if (exception is MyApiException myApiex)
            {
                context.HttpContext.Response.StatusCode = 200;
                context.ExceptionHandled = true;
                result.ErrMsg = myApiex.Msg;
                result.ErrCode = myApiex.ErrCode;
            }
            else
            {
                result.ErrMsg = "程序异常,服务端出现异常![异常消息]" + exception.Message;
                result.ErrCode = "500";
            }
            //Log4NetHelper.Error(type, "全局捕获程序运行异常信息\n\r", context.Exception);

            context.Result = new JsonResult(result);
            var headers = httpRequest.Headers;
            var clientInfo = headers.ContainsKey("User-Agent") ? Parser.GetDefault().Parse(headers["User-Agent"]) : null;
            var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
            var ip = httpContext.GetClientUserIp();
            Log logEntity = new Log()
            {
                Date = DateTime.Now,
                //Account = Appsettings.UserClaims?.FindFirstValue(YuebonClaimConst.UserName),
                Account = "",
                //RealName = Appsettings.UserClaims?.FindFirstValue(YuebonClaimConst.RealName),
                RealName = "",
                IPAddress = ip,
                RequestUrl = httpRequest.Path,
                OS = clientInfo?.OS.Family + clientInfo?.OS.Major,
                Browser = clientInfo?.UA.Family + clientInfo?.UA.Major,
                MethodName = actionDescriptor?.ActionName,
                RequestMethod = httpRequest.Method,
                ExceptionType = exception.GetType().Name,
                Description = $"异常信息：{exception.Message} \r\n【堆栈调用】：\r\n{exception.StackTrace}"
            };

            _service.Insert(logEntity);
        }
    }
}
